package com.heima.gateway.filter;
import com.heima.gateway.util.AppJwtUtil;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * @Author：shenkunlin
 * @date： 2021/9/24 15:51
 * @Description：
 *  局部过滤器：过滤器的名字后部分为GatewayFilterFactory
 *             前部分名字自己定义
 *             需要实现GatewayFilterFactory接口或者继承AbstractGatewayFilterFactory抽象类
 ***/
@Component
public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory {

    /**
     * 拦截方法
     * @param config
     * @return
     */
    @Override
    public GatewayFilter apply(Object config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                /***
                 * 拦截代码：拦截指定服务，过滤游客，游客禁止访问指定的服务
                 */
                //0)获取request[封装了用户请求信息]，response[用于封装响应信息]
                ServerHttpRequest request = exchange.getRequest();
                ServerHttpResponse response = exchange.getResponse();

                //跳过登录页面
                String path = request.getURI().getPath();
                if(path.contains("/login")){
                    return chain.filter(exchange);
                }

                //1)获取请求头中token
                String token = request.getHeaders().getFirst("token");

                //2)解析令牌，判断令牌是否有效
                //3)如果令牌有效，则判断是否是游客，如果是游客，则拦截
                if(!AppJwtUtil.verifyToken(token) || "0".equals(AppJwtUtil.getClaimsBody(token).get("id").toString())){
                    //令牌无效拦截
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    //设置数据类型  json
                    response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                    //响应数据
                    return response.writeWith(Flux.just(response.bufferFactory().wrap("请登录！".getBytes())));
                }
                return chain.filter(exchange);
            }
        };
    }
}
